[HVM] Save/restore: misc tidying
authorTim Deegan <Tim.Deegan@xensource.com>
Mon, 5 Feb 2007 11:38:22 +0000 (11:38 +0000)
committerTim Deegan <Tim.Deegan@xensource.com>
Mon, 5 Feb 2007 11:38:22 +0000 (11:38 +0000)
 - Don't save PIT's last-load-time or CPU's vmx-assist bits
 - Reorder save as cpu, PICs, irqs, timers
 - Save the correct value in the HPET's counter.

Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
xen/arch/x86/hvm/hpet.c
xen/arch/x86/hvm/i8254.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/vpt.h
xen/include/public/hvm/save.h

index dcc6ca3a4db07f49919a47f631cdcffb6bb5a103..6269e149a870d5ce00ff7ee5ea1bca86b14cec1c 100644 (file)
@@ -383,6 +383,9 @@ static int hpet_save(struct domain *d, hvm_domain_context_t *h)
 {
     HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet;
 
+    /* Write the proper value into the main counter */
+    hp->hpet.mc64 = hp->mc_offset + hvm_get_guest_time(hp->vcpu);
+
     /* Save the HPET registers */
     return hvm_save_entry(HPET, 0, h, &hp->hpet);
 }
index 5473f914f4ab41525ea0ae5674ab4028cd04b60d..11ae4ff0cad2a7cc2b52f97ce980a8af35076677 100644 (file)
@@ -83,8 +83,8 @@ static int pit_get_count(PITState *s, int channel)
     struct hvm_hw_pit_channel *c = &s->hw.channels[channel];
     struct periodic_time *pt = &s->pt[channel];
 
-    d = muldiv64(hvm_get_guest_time(pt->vcpu) 
-                 - c->count_load_time, PIT_FREQ, ticks_per_sec(pt->vcpu));
+    d = muldiv64(hvm_get_guest_time(pt->vcpu) - s->count_load_time[channel],
+                 PIT_FREQ, ticks_per_sec(pt->vcpu));
     switch(c->mode) {
     case 0:
     case 1:
@@ -110,7 +110,7 @@ int pit_get_out(PITState *pit, int channel, int64_t current_time)
     uint64_t d;
     int out;
 
-    d = muldiv64(current_time - s->count_load_time
+    d = muldiv64(current_time - pit->count_load_time[channel]
                  PIT_FREQ, ticks_per_sec(pit->pt[channel].vcpu));
     switch(s->mode) {
     default:
@@ -153,7 +153,7 @@ void pit_set_gate(PITState *pit, int channel, int val)
     case 5:
         if (s->gate < val) {
             /* restart counting on rising edge */
-            s->count_load_time = hvm_get_guest_time(pt->vcpu);
+            pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu);
 //            pit_irq_timer_update(s, s->count_load_time);
         }
         break;
@@ -161,7 +161,7 @@ void pit_set_gate(PITState *pit, int channel, int val)
     case 3:
         if (s->gate < val) {
             /* restart counting on rising edge */
-            s->count_load_time = hvm_get_guest_time(pt->vcpu);
+            pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu);
 //            pit_irq_timer_update(s, s->count_load_time);
         }
         /* XXX: disable/enable counting */
@@ -177,8 +177,8 @@ int pit_get_gate(PITState *pit, int channel)
 
 void pit_time_fired(struct vcpu *v, void *priv)
 {
-    struct hvm_hw_pit_channel *s = priv;
-    s->count_load_time = hvm_get_guest_time(v);
+    uint64_t *count_load_time = priv;
+    *count_load_time = hvm_get_guest_time(v);
 }
 
 static inline void pit_load_count(PITState *pit, int channel, int val)
@@ -190,7 +190,7 @@ static inline void pit_load_count(PITState *pit, int channel, int val)
 
     if (val == 0)
         val = 0x10000;
-    s->count_load_time = hvm_get_guest_time(pt->vcpu);
+    pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu);
     s->count = val;
     period = DIV_ROUND((val * 1000000000ULL), PIT_FREQ);
 
@@ -203,7 +203,7 @@ static inline void pit_load_count(PITState *pit, int channel, int val)
             val,
             period,
             s->mode,
-            (long long)s->count_load_time);
+            (long long)pit->count_load_time[channel]);
 #endif
 
     /* Choose a vcpu to set the timer on: current if appropriate else vcpu 0 */
@@ -216,11 +216,13 @@ static inline void pit_load_count(PITState *pit, int channel, int val)
     switch (s->mode) {
         case 2:
             /* create periodic time */
-            create_periodic_time(v, pt, period, 0, 0, pit_time_fired, s);
+            create_periodic_time(v, pt, period, 0, 0, pit_time_fired, 
+                                 &pit->count_load_time[channel]);
             break;
         case 1:
             /* create one shot time */
-            create_periodic_time(v, pt, period, 0, 1, pit_time_fired, s);
+            create_periodic_time(v, pt, period, 0, 1, pit_time_fired,
+                                 &pit->count_load_time[channel]);
 #ifdef DEBUG_PIT
             printk("HVM_PIT: create one shot time.\n");
 #endif
@@ -387,7 +389,7 @@ static void pit_info(PITState *pit)
         printk("pit 0x%x.\n", s->mode);
         printk("pit 0x%x.\n", s->bcd);
         printk("pit 0x%x.\n", s->gate);
-        printk("pit %"PRId64"\n", s->count_load_time);
+        printk("pit %"PRId64"\n", pit->count_load_time[i]);
 
         pt = &pit->pt[i];
         if (pt) {
index a35b84848df4b10d11ca6f49decdb6132f643f8f..76112e14ef5dbcfca8c733c3b13e569b751093cc 100644 (file)
@@ -591,6 +591,7 @@ void svm_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
+    vmcb->kerngsbase = data->shadow_gs;
     /* MSR_LSTAR, MSR_STAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_EFER */
     vmcb->lstar  = data->msr_items[0];
     vmcb->star   = data->msr_items[1];
index 8a8691c383efe7b89c49c462225b7a06e02f433f..0a4c008b374c180c2cafbda5bbd68f455a53d61c 100644 (file)
@@ -588,7 +588,7 @@ void vmx_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
     int i = 0;
 
     data->shadow_gs = guest_state->shadow_gs;
-    data->vmxassist_enabled = v->arch.hvm_vmx.vmxassist_enabled;
+
     /* save msrs */
     data->flags = guest_flags;
     for (i = 0; i < VMX_MSR_COUNT; i++)
@@ -611,10 +611,7 @@ void vmx_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
 
     guest_state->shadow_gs = data->shadow_gs;
 
-    /*XXX:no need to restore msrs, current!=vcpu as not called by arch_vmx_do_launch */
-/*    vmx_restore_guest_msrs(v);*/
-
-    v->arch.hvm_vmx.vmxassist_enabled = data->vmxassist_enabled;
+    v->arch.hvm_vmx.vmxassist_enabled = !(data->cr0 & X86_CR0_PE);
 
     hvm_set_guest_time(v, data->tsc);
 
index 78684044266c12c9ea5b8dd2f846146f5e6a9ca8..78c7b536d420671b36dc3c5801fd59982b48ee4d 100644 (file)
@@ -66,7 +66,7 @@ struct periodic_time {
     u64 last_plt_gtime;         /* platform time when last IRQ is injected */
     struct timer timer;         /* ac_timer */
     time_cb *cb;
-    void *priv;                 /* ponit back to platform time source */
+    void *priv;                 /* point back to platform time source */
 };
 
 
@@ -76,6 +76,8 @@ struct periodic_time {
 typedef struct PITState {
     /* Hardware state */
     struct hvm_hw_pit hw;
+    /* Last time the counters read zero, for calcuating counter reads */
+    int64_t count_load_time[3];
     /* irq handling */
     struct periodic_time pt[3];
 } PITState;
index 48dfc187f0d6232c7baa324133c28bca9985fb83..c17075af7247253fda1b65ee4c0f0a76676a19fc 100644 (file)
@@ -140,13 +140,10 @@ struct hvm_hw_cpu {
     uint64_t sysenter_esp;
     uint64_t sysenter_eip;
 
-    /* msr for em64t */
+    /* MSRs */
     uint64_t shadow_gs;
     uint64_t flags;
-
-    /* same size as VMX_MSR_COUNT */
     uint64_t msr_items[6];
-    uint64_t vmxassist_enabled;
 
     /* guest's idea of what rdtsc() would return */
     uint64_t tsc;
@@ -155,32 +152,6 @@ struct hvm_hw_cpu {
 DECLARE_HVM_SAVE_TYPE(CPU, 2, struct hvm_hw_cpu);
 
 
-/* 
- *  PIT
- */
-
-struct hvm_hw_pit {
-    struct hvm_hw_pit_channel {
-        int64_t count_load_time;
-        uint32_t count; /* can be 65536 */
-        uint16_t latched_count;
-        uint8_t count_latched;
-        uint8_t status_latched;
-        uint8_t status;
-        uint8_t read_state;
-        uint8_t write_state;
-        uint8_t write_latch;
-        uint8_t rw_mode;
-        uint8_t mode;
-        uint8_t bcd; /* not supported */
-        uint8_t gate; /* timer start */
-    } channels[3];  /* 3 x 24 bytes */
-    uint32_t speaker_data_on;
-};
-
-DECLARE_HVM_SAVE_TYPE(PIT, 3, struct hvm_hw_pit);
-
-
 /*
  * PIC
  */
@@ -233,7 +204,7 @@ struct hvm_hw_vpic {
     uint8_t int_output;
 };
 
-DECLARE_HVM_SAVE_TYPE(PIC, 4, struct hvm_hw_vpic);
+DECLARE_HVM_SAVE_TYPE(PIC, 3, struct hvm_hw_vpic);
 
 
 /*
@@ -275,7 +246,27 @@ struct hvm_hw_vioapic {
     } redirtbl[VIOAPIC_NUM_PINS];
 };
 
-DECLARE_HVM_SAVE_TYPE(IOAPIC, 5, struct hvm_hw_vioapic);
+DECLARE_HVM_SAVE_TYPE(IOAPIC, 4, struct hvm_hw_vioapic);
+
+
+/*
+ * LAPIC
+ */
+
+struct hvm_hw_lapic {
+    uint64_t             apic_base_msr;
+    uint32_t             disabled; /* VLAPIC_xx_DISABLED */
+    uint32_t             timer_divisor;
+};
+
+DECLARE_HVM_SAVE_TYPE(LAPIC, 5, struct hvm_hw_lapic);
+
+struct hvm_hw_lapic_regs {
+    /* A 4k page of register state */
+    uint8_t  data[0x400];
+};
+
+DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 6, struct hvm_hw_lapic_regs);
 
 
 /*
@@ -344,26 +335,32 @@ struct hvm_hw_irq {
     u8 round_robin_prev_vcpu;
 };
 
-DECLARE_HVM_SAVE_TYPE(IRQ, 6, struct hvm_hw_irq);
-
-/*
- * LAPIC
- */
+DECLARE_HVM_SAVE_TYPE(IRQ, 7, struct hvm_hw_irq);
 
-struct hvm_hw_lapic {
-    uint64_t             apic_base_msr;
-    uint32_t             disabled; /* VLAPIC_xx_DISABLED */
-    uint32_t             timer_divisor;
-};
 
-DECLARE_HVM_SAVE_TYPE(LAPIC, 7, struct hvm_hw_lapic);
+/* 
+ *  PIT
+ */
 
-struct hvm_hw_lapic_regs {
-    /* A 4k page of register state */
-    uint8_t  data[0x400];
+struct hvm_hw_pit {
+    struct hvm_hw_pit_channel {
+        uint32_t count; /* can be 65536 */
+        uint16_t latched_count;
+        uint8_t count_latched;
+        uint8_t status_latched;
+        uint8_t status;
+        uint8_t read_state;
+        uint8_t write_state;
+        uint8_t write_latch;
+        uint8_t rw_mode;
+        uint8_t mode;
+        uint8_t bcd; /* not supported */
+        uint8_t gate; /* timer start */
+    } channels[3];  /* 3 x 16 bytes */
+    uint32_t speaker_data_on;
 };
 
-DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 8, struct hvm_hw_lapic_regs);
+DECLARE_HVM_SAVE_TYPE(PIT, 8, struct hvm_hw_pit);
 
 
 /*